/*
 * @Author: Swance
 * @Date: 2023-12-30
 * @Description: 拖拽画布插件
 */
import { fabric } from 'fabric';
import { IEditor } from '@/types/global';

class DragCanvasPlugin {
  canvas: fabric.Canvas;
  editor: IEditor;
  isDragging: boolean;
  dragMode: boolean;
  lastPosX: number;
  lastPosY: number;
  static pluginName = 'DragCanvasPlugin';
  static apis: string[] = ['setDragMode'];

  constructor(canvas: fabric.Canvas, editor: IEditor) {
    this.canvas = canvas;
    this.editor = editor;
    this.dragMode = false;
    this.isDragging = false;
    this.lastPosX = 0;
    this.lastPosY = 0;
    this.init();
  }

  init() {
    const { canvas } = this;
    canvas.on('mouse:down:before', (e) => {
      if (!this.dragMode) return;
      canvas.selection = false;
      //取消画布中所有对象的选中状态
      canvas.discardActiveObject();
      canvas.getObjects().forEach((obj) => {
        // 禁止选中画布元素
        obj.selectable = false;
        // 隐藏画布元素的控制角，使其旋转、缩放
        obj.hasControls = false;
      });
      // 异步重绘画布内容，它会在下一次浏览器的重绘周期中重新渲染画布
      canvas.requestRenderAll();
      this.lastPosX = e.e.clientX;
      this.lastPosY = e.e.clientY;
      this.isDragging = true;
    });

    canvas.on('mouse:move', (e) => {
      if (!this.isDragging) return;
      canvas.selection = false;
      // 取消画布中所有元素的选中状态
      canvas.discardActiveObject();
      const vpt = canvas.viewportTransform; // 聚焦视图的转换
      vpt[4] += e.e.clientX - this.lastPosX;
      vpt[5] += e.e.clientY - this.lastPosY;
      this.lastPosX = e.e.clientX;
      this.lastPosY = e.e.clientY;
      canvas.requestRenderAll();
    });

    canvas.on('mouse:up', () => {
      if (!this.isDragging) return;
      canvas.setViewportTransform(canvas.viewportTransform);
      canvas.selection = true;
      this.isDragging = false;
      // 取消画布中所有元素的选中状态
      canvas.discardActiveObject();
    });
  }

  setDragMode(param: boolean) {
    this.dragMode = param;
    if (this.dragMode) {
      this.canvas.defaultCursor = 'grab';
      this.canvas.hoverCursor = 'grab';
    } else {
      this.canvas.defaultCursor = 'default';
      this.canvas.hoverCursor = 'move';
      this.resume();
    }
  }

  // 恢复画布中所有元素的可选择和可点击
  resume() {
    this.canvas.getObjects().forEach((obj) => {
      obj.selectable = true;
      obj.hasControls = true;
      obj.evented = true;
    });
  }
}
export default DragCanvasPlugin;
